#ifndef WINAPI_INCLUDED

#define _WIN32_WINNT 0x550
//#define READ_ONLY
//#define WIN98
#include "windows.h"
#include <errors.h>
#include <io.h>
#include <fcntl.h>

int setUnblocking(int);
int initWindows();
#define initApi() initWindows();
#define TIME_T long
#define FSLASH '\\'
#define SLASH '/'
#define CONSOLE "conout$"
#define timeLocal time(NULL)-timez
#define filenamecmp stricmp

#define ULONG DWORD
#define UCHAR unsigned char
#define INVALID_HANDLE INVALID_HANDLE_VALUE
#define HDIR HANDLE
#define TID HANDLE
#define HEV HANDLE
#define HMTX HANDLE
#define THREADFN ULONG APIENTRY
#define EXIT_THREAD_FN return 0;

#define PFNTHREAD LPTHREAD_START_ROUTINE 
#define FNTHREAD THREAD_START_ROUTINE 
/* File Functions */

		/*file open actions*/

#define ACTION_OPEN_IF_EXISTS OPEN_EXISTING
#define ACTION_CREATE_NEW CREATE_NEW
#define ACTION_TRUNCATE_EXISTING	TRUNCATE_EXISTING

		/*file access modes */
#define FILE_ACCESS_READONLY GENERIC_READ
#define FILE_ACCESS_WRITEONLY GENERIC_WRITE
#ifdef READ_ONLY
#define FILE_ACCESS_READWRITE	GENERIC_READ
#else
#define FILE_ACCESS_READWRITE	GENERIC_READ|GENERIC_WRITE
#endif
#define FILE_ACCESS_NONE	0
	     /*file share modes */
#ifdef WIN98
#define FILE_SHARE_ALL 0
#else
#define FILE_SHARE_ALL FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE
#endif
#define FILE_SHARE_READONLY	FILE_SHARE_READ
#define FILE_SHARE_WRITEONLY FILE_SHARE_WRITE
#define FILE_SHARE_NONE	0

		/* open flags */

#define ACCESS_FLAGS_RANDOM FILE_FLAG_RANDOM_ACCESS
//#define ACCESS_FLAGS_SYNCWRITE FILE_FLAG_WRITE_THROUGH
#define ACCESS_FLAGS_SEQUENTIAL FILE_FLAG_SEQUENTIAL_SCAN
#define ACCESS_FLAGS_NORMAL 0
	     /* create flags */
#define ATTRIBUTE_NORMAL FILE_ATTRIBUTE_NORMAL
#define INVALID_FILE_POINTER 0xFFFFFFFF


#define HFILE HANDLE
#define FROM_BEGINNING FILE_BEGIN
#define FROM_END	FILE_END
#define FROM_CURRENT	FILE_CURRENT

#define FlushFile(handle) FlushFileBuffers(handle)
#define FileRead(handle,buff,bytestoread,bytesread,success) success=ReadFile(handle,buff,bytestoread,&bytesread,NULL)
#define FileWrite(handle,buff,bytestowrite,byteswritten,success) success=WriteFile(handle,buff,bytestowrite,&byteswritten,NULL)
#define FileClose(handle,success) success=CloseHandle(handle)
#define PipeCreate(h1,h2,psize,success)\
 SECURITY_ATTRIBUTES sa;\
 sa.lpSecurityDescriptor=NULL;\
 sa.bInheritHandle=TRUE;\
 sa.nLength=sizeof(SECURITY_ATTRIBUTES);\
 success=CreatePipe(&h1,&h2,&sa,(psize*2))

#define FileDelete(fname,success) success=(DeleteFile(fname)?1:(GetLastError()<4))
//#define FileLock(handle,success) OVERLAPPED x;x.Offset=0;x.OffsetHigh=0;x.hEvent=0;success=LockFileEx(handle,LOCKFILE_EXCLUSIVE_LOCK,0,512,0,&x)?1:0;
#define FileLock(handle,success) success=LockFile(handle,0,512,512,0);
#define FileOpen(filename,handle,action,accessmode,sharemode,openmode,attributes,success) success=((handle=CreateFile(filename,accessmode,sharemode,NULL,action,openmode|attributes,NULL))!=INVALID_HANDLE_VALUE)
#define FileSeek(handle,offset,from,newptr,success) success=(((newptr=SetFilePointer(handle,offset,NULL,from))==INVALID_FILE_POINTER) && (GetLastError()!=NO_ERROR))?0:1
#define FileMove(fname,newname,success) success=MoveFile(fname,newname);
#define GetFileTimeLastWrite(handle,t)\
 struct tm tms;\
 FILETIME ctime,mtime;\
 if (GetFileTime(handle,&ctime,NULL,&mtime)) {\
				SYSTEMTIME tmp;\
				FileTimeToSystemTime(&mtime,&tmp);tms.tm_year=tmp.wYear-1900;tms.tm_mday=tmp.wDay;tms.tm_mon=tmp.wMonth-1;tms.tm_hour=tmp.wHour;tms.tm_sec=tmp.wSecond;tms.tm_min=tmp.wMinute;\
				t=mktime(&tms)-timezone;\
 				FileTimeToSystemTime(&ctime,&tmp);tms.tm_year=tmp.wYear-1900;tms.tm_mday=tmp.wDay;tms.tm_mon=tmp.wMonth-1;tms.tm_hour=tmp.wHour;tms.tm_sec=tmp.wSecond;tms.tm_min=tmp.wMinute;\
				ULONG tc=mktime(&tms)-timezone;\
				if(tc>t) t=tc;\
}



#define SetDateTime(t) {\
 struct tm tms;\
 mktm(t+timezone,&tms);\
 SYSTEMTIME tmp; tmp.wMilliseconds=0;tmp.wMonth=tms.tm_mon+1;tmp.wHour=tms.tm_hour;tmp.wSecond=tms.tm_sec;tmp.wMinute=tms.tm_min;tmp.wYear=tms.tm_year+1900;tmp.wDay=tms.tm_mday;\
 SetSystemTime(&tmp);\
}

#define SetFileTimeLastWrite(fname,handle,t,success) {\
 struct tm tms;\
 mktm(t+timezone,&tms);\
 success=0;\
 FILETIME ftime; SYSTEMTIME tmp;tmp.wMilliseconds=0;tmp.wMonth=tms.tm_mon+1;tmp.wHour=tms.tm_hour;tmp.wSecond=tms.tm_sec;tmp.wMinute=tms.tm_min;tmp.wYear=tms.tm_year+1900;tmp.wDay=tms.tm_mday;if(SystemTimeToFileTime(&tmp,&ftime)) success=SetFileTime(handle,&ftime,&ftime,&ftime);\
 }\

#define DirectoryCreate(name,success) success=CreateDirectory(name,NULL)
#define DirectoryDelete(name,success) success=RemoveDirectory(name);\
if(success==0) {if (GetLastError()<=4) success=1;}
#define SetMaxHandles(n,success) success=1;

/* Time functions	*/

#define convertFileTime(t,ftime,fdate) \
{\
 SYSTEMTIME tmp;\
 FileTimeToSystemTime(&ftime,&tmp);\
 struct tm tms;\
 tms.tm_year=tmp.wYear-1900;\
 tms.tm_mday=tmp.wDay;\
 tms.tm_mon=tmp.wMonth-1;\
 tms.tm_hour=tmp.wHour;\
 tms.tm_sec=tmp.wSecond;\
 tms.tm_min=tmp.wMinute;\
 t=mktime(&tms)-timezone;\
}\

/* File Find Functions */

#define ftimeLastWrite ftLastWriteTime
#define fdateLastWrite  0
#define ftimeCreation   ftCreationTime
#define fdateCreation    0
#define FILEFINDBUF	WIN32_FIND_DATA 
#define attrFile  dwFileAttributes
#define achName cFileName  
#define cbFile nFileSizeLow
#define FinderClose(hndl) FindClose(hndl)
#define ARCHIVE_FILE FILE_ATTRIBUTE_ARCHIVE
#define DIRECTORY_FILE FILE_ATTRIBUTE_DIRECTORY
#define NORMAL_FILE FILE_ATTRIBUTE_NORMAL
#define NULLHDIR (HDIR)0xffffffff

#define	SetFileAttribute(handle,filename,flag,on) \
	ULONG attr=GetFileAttributes(filename);\
	if(on) \
		attr|=flag;\
	else \
		attr&=~flag;\
	SetFileAttributes(filename,attr);


#ifdef WIN98
#define SEARCHOPTION int
#define FILEONLY FILE_ATTRIBUTE_NORMAL
#define DIRONLY FILE_ATTRIBUTE_DIRECTORY
#define FILEANY FILE_ATTRIBUTE_NORMAL

#define FindFirst(filePattern,hndl,attribute,findbuff,success) \
		success=((hndl=FindFirstFile( filePattern,&findbuff))!=INVALID_HANDLE_VALUE)
#else
#define SEARCHOPTION FINDEX_SEARCH_OPS



#define FILEONLY FindExSearchNameMatch
#define DIRONLY FindExSearchLimitToDirectories
#define FILEANY FindExSearchNameMatch


#define FindFirst(filePattern,hndl,attribute,findbuff,success)\
		success=((hndl=FindFirstFileEx( filePattern, \
                 FindExInfoStandard, \
                 &findbuff, \
                 attribute, \
                 NULL, \
                 0 ))!=INVALID_HANDLE_VALUE)
#endif
#define FindNext(handle,findbuff,success) success=FindNextFile(handle,&findbuff)


/* semaphores */

#define makeMutexSem(hmtx,success) success=(hmtx=CreateMutex(0,0,0))!=NULL
#define makeEventSem(hwait,success)	success=(hwait=CreateEvent(NULL,0,0,NULL))!=NULL
#define RequestMutexSem(hmtx,dwMilSec) WaitForSingleObject(hmtx,dwMilSec)
#define ReleaseMutexSem(hmtx) ReleaseMutex(hmtx)
#define CloseMutexSem(hmtx) CloseHandle(hmtx);hmtx=0;
#define CloseEventSem(hevent) CloseHandle(hevent);hevent=0;
#define ResetEventSem(x) ResetEvent(x)
#define PostEventSem(hwait) SetEvent(hwait)
#define WaitEventSem(hevent,dwMilSec,success)\
	int rs;\
	success=((rs=WaitForSingleObject(hevent,dwMilSec))!=WAIT_FAILED);\
	if(rs==WAIT_TIMEOUT) success=640;


/* critical sections */
//extern  CRITICAL_SECTION CriticalSection; 
//extern  CRITICAL_SECTION MemSection; 

extern HMTX TSmtx;
extern HMTX CSmtx;


//#define EnterMemSec() RequestMutexSem(TSmtx,INFINITE)
//#define ExitMemSec()  ReleaseMutexSem(TSmtx)
#define EnterMemSec()
#define ExitMemSec() 

//#define EnterMemSec()   incmemc();while(memc>1) {decmemc();Sleep(1);incmemc();}
//#define ExitMemSec()    decmemc();
//#define EnterCritSec()   cs++;while(cs>1) {--cs;Sleep(1);++cs;}
//#define ExitCritSec()    cs--;
#define EnterCritSec() RequestMutexSem(CSmtx,INFINITE)
#define ExitCritSec()  ReleaseMutexSem(CSmtx)


/* processes and threads*/
#define EnterMustComplete() SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)
#define ExitMustComplete() SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL)

#define getThreadId(tid,success) success=((tid=GetCurrentThreadId())!=0)
#define getProcessId(pid,success) success=((pid=GetCurrentProcessId())!=0)
#define SetPriorityServer()  SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS)
#define SetCurrentThreadPriorityHighest()  SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST)
#define SetThreadPriorityHighest(tid)  SetThreadPriority(tid,THREAD_PRIORITY_HIGHEST)
#define SetThreadPriorityLowest(tid)  SetThreadPriority(tid,THREAD_PRIORITY_LOWEST)
extern u_long THREAD_ID;
#define ThreadCreate(thandle,threadFunc,pRunnable,stackSize,success)  success=((thandle=CreateThread(NULL,stackSize,threadFunc,pRunnable,0,&THREAD_ID))!=NULL); 
#define KillThread(thandle)	TerminateThread(thandle,0);CloseHandle(thandle);
#define ThreadSuspend(thandle) SuspendThread(thandle)
#define ThreadResume(thandle) ResumeThread(thandle)
#define SleepMilSec(n) Sleep(n)
#define GetClockTicks() GetTickCount()
#define FreeThreadResources(thandle) CloseHandle(thandle);thandle=NULL
#define ExecuteProgram(prgname,pars,returncode,success,fo)\
	HANDLE fhandle=0;\
	if(fo){\
     SECURITY_ATTRIBUTES sa;\
     memset( &sa, 0, sizeof(sa) );\
	 sa.lpSecurityDescriptor =NULL;\
     sa.nLength=sizeof(sa);\
	 sa.bInheritHandle=TRUE;\
	 fo->close();\
     fhandle=CreateFile(fo->getName(),GENERIC_READ|GENERIC_WRITE,0,&sa,OPEN_EXISTING,NORMAL_FILE,NULL);\
	Buffer *prg = new Buffer(strlen(prgname)+strlen(pars+1)+2);\
    snprintf(*prg,prg->getSize(),"%s %s",prgname,pars+1);\
    STARTUPINFO si;\
    PROCESS_INFORMATION pi;\
    memset( &si, 0, sizeof(si) );\
    si.cb = sizeof(si);\
	si.dwFlags=STARTF_USESTDHANDLES;\
	si.hStdOutput=fhandle;\
    /* Start the child process. */\
    if(success = CreateProcess( \
	    NULL,/* No module name (use command line). */\
        *prg,/* Command line. */\
        NULL,            /* Process handle not inheritable. */\
        NULL,            /* Thread handle not inheritable. */\
        TRUE,           /* Set handle inheritance to TRUE. */\
        CREATE_NO_WINDOW|DETACHED_PROCESS,               /* No creation flags. */\
        NULL,            /* Use parent's environment block. */\
        NULL,            /* Use parent's starting directory. */\
        &si,             /* Pointer to STARTUPINFO structure.*/\
        &pi )            /* Pointer to PROCESS_INFORMATION structure.*/\
		) {\
    /*Wait until child process exits.*/\
    if(success=(WaitForSingleObject( pi.hProcess, INFINITE )!=WAIT_FAILED))\
      success=GetExitCodeProcess(pi.hProcess,(ULONG*)&returncode);\
   /*Close process and thread handles.*/\
    if (fhandle>0)   CloseHandle(fhandle);\
    CloseHandle( pi.hProcess );\
    CloseHandle( pi.hThread );\
    } \
	delete prg;\
	}

#define WINAPI_INCLUDED

#endif

